/********************************************************
 Name          : startup.c
 Author        : Khachatur Gyozalyan
 Copyright     : Copyright by Antel Systems
 Description   :
 **********************************************************/
// Include Files
#include "startup.h"
#include "board.h"
#include "pm.h"
#include "intc.h"
#include "board.h"
#include "print_funcs.h"
#include "clocks.h"
#include "wdt.h"
#include "llc_if.h"
#include "lwip/init.h"
#include "CMX7164.h"
#include "CMX998.h"
#include "CMX994.h"
#include "LMX2541.h"
#include "file_system.h"
#include "network.h"
#include "llc/llc.h"
#include "mac/mac.h"
#include "tc_1.h"
#include "AntelCfgOID.h"
#include "cmx7164_api.h"
#include "USB_if.h"
#include "sleep_s.h"
#include "ADC_api.h"
#include "common_def.h"
#include "sky72310.h"

static void init_exceptions(void)
{
	extern void _evba;
	Set_system_register(AVR32_EVBA, (int)&_evba);
	Enable_global_exception();
}

static void init_hmatrix(void)
{
	union {
		unsigned long                 scfg;
		avr32_hmatrix_scfg_t          SCFG;
	} u_avr32_hmatrix_scfg = { 
		AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH]
	};
	u_avr32_hmatrix_scfg.SCFG.defmstr_type = 
		AVR32_HMATRIX_DEFMSTR_TYPE_LAST_DEFAULT;
	AVR32_HMATRIX.scfg[AVR32_HMATRIX_SLAVE_FLASH] = 
		u_avr32_hmatrix_scfg.scfg;
}

static void init_interrupts(void)
{
	//INTC_init_interrupts();
	Enable_global_interrupt();
}

void spi_bus_init(void)
{
	static const gpio_map_t SPI_GPIO_MAP =
	{
		{SPI_SCK_PIN,          SPI_SCK_FUNCTION         },  // SPI Clock.
		{SPI_MISO_PIN,         SPI_MISO_FUNCTION        },  // MISO.
		{SPI_MOSI_PIN,         SPI_MOSI_FUNCTION        },  // MOSI.
		{AT25DFX_SPI_NPCS_PIN, AT25DFX_SPI_NPCS_FUNCTION},  // Chip Select NPCS AT25DFX.
		{HDG104_SPI_NPCS_PIN,  HDG104_SPI_NPCS_FUNCTION},   // Chip Select NPCS HDG104.
		{CMX7164_SPI_NPCS_PIN, CMX7164_SPI_NPCS_FUNCTION}	// Chip Select NPCS CMX7164.
	};

	// SPI options.
	spi_options_t spiOptions =
	{
		.reg          = 0,
		.baudrate     = SPI_MASTER_SPEED, // Defined in conf_at25dfx.h.
		.bits         = SPI_BITS,         // Defined in conf_at55dfx.h.
		.spck_delay   = 0,
		.trans_delay  = 0,
		.stay_act     = 1,
		.spi_mode     = 0,
		.modfdis      = 1
	};

	// Assign I/Os to SPI.
	gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0]));

	// Initialize as master.
	spi_initMaster(SPI_MODULE, &spiOptions);

	// Set selection mode: variable_ps, pcs_decode, delay.
	spi_selectionMode(SPI_MODULE, 0, 0, 0);

	// Enable SPI.
	spi_enable(SPI_MODULE);

	// Initialize SPI clock.
	spiOptions.reg = AT25DFX_SPI_NPCS;
	spi_setupChipReg(SPI_MODULE, &spiOptions, FMCK_HZ);

  spiOptions.reg = CMX7164_SPI_NPCS;
	spi_setupChipReg(SPI_MODULE, &spiOptions, FMCK_HZ);
}

void board_init(void)
{
	wdt_disable();
	init_exceptions();
	init_hmatrix();
	init_sys_clocks();
	init_interrupts();
	spi_bus_init();
	CMX7164_IO_Init();
	ADC_Init();
	led_init();
	SKY72310_Init();
}

void system_init(void)
{
	char msg[64];
	led_state_set_color(red);
	led_mode_set_color(green);
	Rtos_started = 0 ;
	TC1_init();
	at25dfx_resources_init();
//	at25dfx_erase_all();
	cfg_init();
	organize_files_operation();
	if(StartupMode == START_UP_NORMAL)
	{
		switch (Get_boot_option())
		{
		case BOOT_OPTION_USER:
			loading_config(0);
			strcpy(msg,"USER OPTONS ARE LOADED.\r\n");
			break;
		case BOOT_OPTION_DEFAULT:
			loading_config(1);
			strcpy(msg,"DEFAULT OPTONS ARE LOADED.\r\n");
			break;
		}
	}
	else if (StartupMode == START_UP_LOAD_DEFAULT)
	{
		loading_config(1);
		strcpy(msg,"DEFAULT OPTONS ARE LOADED, USER CONFIGURATION MISSING.");
	}
	initial_version_struct();

	CfgRoot_init();
	cli_op_mode_init();
	usart_fast_init();
	lwip_init();
	llc_netif_init();
	if (StartupMode != START_UP_REQUIRE_WRITE)
	{
		LMX2541_Init();
		CMX_nInitialized = CMX7164_Initialize();
		CMX_nInitialized += CMX998_Initialize(ConfigRoot.G_Wireless.SG_Uhf.param_output_pow / 2);
		CMX_nInitialized += CMX994_Init();
		CMX_nInitialized += CMX7164_TX_DC_Offset_Calibration();

		switch(CMX7164_Modulation_Type)
		{
			case 1 :
			case 2 :
			case 3 :
				Network_Buffer_Size = NETWORK_BUFFER_SIZE_QAM ;
				break ;
			case 4 :
				Network_Buffer_Size = NETWORK_BUFFER_SIZE_2FSK ;
				break ;
			case 5 :
				Network_Buffer_Size = NETWORK_BUFFER_SIZE_4FSK ;
				break ;
			case 6 :
				Network_Buffer_Size = NETWORK_BUFFER_SIZE_GMSK ;
				break ;

		}

		print_version_info();
		printk("%s",msg);

		if(CMX_nInitialized )
			printk("\r\nStartup Error - %d",CMX_nInitialized );
		else
			CMX7164_Tx_Enable(1);

		sleep_mode_init();
	}
	led_state_set_color(color_off);
}

void rtos_init(void)
{
	cli_task_init();

	network_task_init();

	if (StartupMode != START_UP_REQUIRE_WRITE)
	{
//		wifi_task_init();

		llc_task_init(ConfigRoot.G_Network.SG_NetProtSet.param_bridging_reg.pmp);//aaaaaaaaaaaaaaaaaaaaaaa

		mac_task_init();
	}
//	usb_if_task_init();//aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
	Rtos_started = 1 ;
	usart_rx_en();

	vTaskStartScheduler();
}


